package server;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;

public class GpcRequestProcessor {

	//构造线程池
	public static void ProcessorRequest(SelectionKey key) {
		//获得线程并执行
		
		ByteBuffer readBuf = ByteBuffer.allocate(1024);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		SocketChannel sc = null;
		try {
			sc = (SocketChannel) key.channel();
			// 注册观察者
			GpcRequestHandler.addObserver(key,new GpcRequestObserver(sc.getRemoteAddress().toString(), key));
			int len = sc.read(readBuf);
			if(len == -1) {
				key.channel().close();
				key.cancel();
				return;
			}
			readBuf.flip();
			while (readBuf.hasRemaining()) {
				baos.write(readBuf.get());
			}
			handleReceiveRequest(baos,key);
			readBuf.clear();
		} catch (IOException | InterruptedException e) {
			try {
				key.channel().close();
				key.cancel();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		} finally {
			try {
				baos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	private static void handleReceiveRequest(ByteArrayOutputStream baos,SelectionKey key) throws IOException, InterruptedException {
		GpcRequest receive = unserialize(baos.toByteArray());
		if(receive!=null) {
			//注册新筛选器
			ConnectionServer.addNewSelection(key);
			//将收到的消息进行预处理
			preResponseHeader(receive);
			//将接收得消息推入队列中
			GpcRequestHandler.receive(key, receive);
			//打印消息
			//System.out.println("服务器端接收到的数据："+ receive+" from "+key.toString());
		}
		baos.reset();
	}

	private static void preResponseHeader(GpcRequest receive) {
		if("-1".equals(receive.getHeaders().get(GpcRequestHandler.X_ENTITY_ID))) {
			receive.setHeader(GpcRequestHandler.X_ENTITY_ID, String.valueOf(ConnectionServer.idGenerator.incrementAndGet()));
		}
	}

	/**
	 * 将byte[] -->Object
	 * @param bytes
	 * @return
	 */
	private static GpcRequest unserialize(byte[] bytes) {
		ByteArrayInputStream bais = null;
		try {
			// 反序列化
			bais = new ByteArrayInputStream(bytes);
			ObjectInputStream ois = new ObjectInputStream(bais);
			return (GpcRequest) ois.readObject();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				bais.close();
			} catch (IOException e) {
				//logger.error("{}", e);
			}
		}
		return null;
	}

}
